package com.taglab.chic.search.impl;

import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.XMLEvent;
import java.io.InputStream;
import java.io.IOException;

import com.taglab.chic.search.Hit;

/**
 * XXX needs a lot of work
 *
 * @author Markus Kobler
 */
class OpenSearchXMLParser {

  private final static String openSearch10NS = "http://a9.com/-/spec/opensearchrss/1.0/";
  private final static String openSearch11NS = "http://a9.com/-/spec/opensearch/1.1/";

  private final XMLInputFactory inputFactory;

  OpenSearchXMLParser() {
    inputFactory = XMLInputFactory.newInstance();
    inputFactory.setProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, Boolean.FALSE);
  }


  public void parse(InputStream in, ResultBuilder resultBuilder) throws XMLStreamException {

    XMLStreamReader reader = null;

    try {

      reader = inputFactory.createXMLStreamReader(in);

      reader.nextTag();
      if( !"rss".equals(reader.getLocalName()) ) {
        throw new UnsupportedOperationException("Currently can only parse RSS feeds");
      }

      while (reader.hasNext()) {

        switch (reader.next()) {

          case XMLEvent.START_ELEMENT:

            if (reader.getLocalName().equals("totalResults") &&
               (reader.getNamespaceURI().equals(openSearch10NS) || reader.getNamespaceURI().equals(openSearch11NS)) ) {
              try {
                resultBuilder.setTotalResults(Integer.parseInt(reader.getElementText()));
              } catch (NumberFormatException ex) {
                // ignore
              }
            } else if( reader.getLocalName().equals("item") ) {
              processItem(reader, resultBuilder);
            }
            break;
        }
      }

    } finally {

      try {
        if (reader != null) reader.close();
      } catch (XMLStreamException ex) { /* ignore */ }

      try {
        if (in != null) in.close();
      } catch (IOException ex) { /* ignore */ }

    }

  }


  protected void processItem(XMLStreamReader reader, ResultBuilder resultBuilder) throws XMLStreamException {
    
    String title = null;
    String description = null;
    String url = null;

    while (reader.hasNext()) {

      switch (reader.next()) {

        case XMLEvent.START_ELEMENT:
          if (reader.getLocalName().equals("title")) {
            title = reader.getElementText();
          } else if (reader.getLocalName().equals("link")) {
            url = reader.getElementText();
          } else if (reader.getLocalName().equals("description")) {
            description = reader.getElementText();
          }
          break;
        case XMLEvent.END_ELEMENT:
          if( reader.getLocalName().equals("item") ) {
            resultBuilder.addResult(new Hit(url, title, description));
          }
          break;
      }
    }
  }

}
